package com.bby.disk.controller;


import cn.hutool.core.util.ObjectUtil;
import com.bby.common.aop.ParseToken;
import com.bby.common.exception.BBYException;
import com.bby.common.model.FileReport;
import com.bby.common.utils.BBYUtils;
import com.bby.common.utils.R;
import com.bby.common.utils.StatusCode;
import com.bby.disk.bean.req.EditPermissionReq;
import com.bby.disk.bean.req.FileActionReq;
import com.bby.disk.bean.vo.FileActionResult;
import com.bby.disk.bean.vo.VirtualFileList;
import com.bby.disk.manager.virtual.VirtualPath;
import com.bby.disk.service.IFileService;
import lombok.NonNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 网盘-网盘操作
 */
@RestController
public class FileController {
    Logger logger = LoggerFactory.getLogger(this.getClass());
    IFileService fileService;

    public FileController(IFileService fileService) {
        this.fileService = fileService;
    }

    /**
     * 搜索
     *
     * @param target  目录id/用户id，为空时全局搜索
     * @param keyword 关键字
     * @param page    分页，默认第一页
     * @param type    文件(file)还是文件夹(dir)还是全部(all)
     * @param limit   每页数量，最少5个,默认 12
     */
    @ParseToken
    @GetMapping("search")
    @ResponseBody
    public R search(String userId, String target,@RequestParam(defaultValue = "all")  String type, @NonNull String keyword,
                    @RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "12") Integer limit) throws BBYException {
        if (limit < 5) {
            limit = 12;
        }
        return R.ok(fileService.search(userId, target, keyword, type, page, limit));
    }

    /**
     * 文件分类，必须登录
     * @param category 分类
     */
    @ParseToken(require = true)
    @GetMapping("classify/{category}")
    @ResponseBody
    public R classify(String userId,@PathVariable String category) throws BBYException {
        return R.ok(fileService.classify(userId, category));
    }

    /**
     * 获取所有课访问的共享盘
     *
     * @param page  分页，最小 1，默认 1
     * @param limit 每页数量，最少5个,默认 12
     */
    @GetMapping("userRoots")
    @ResponseBody
    @ParseToken
    public R userRoots(String userId, @RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "12") Integer limit) {
        if (limit < 5) {
            limit = 12;
        }
        return R.ok(fileService.getUserRoots(userId, page, limit));
    }

    /**
     * 获取单个文件信息
     *
     * @param fileId 文件id
     */
    @GetMapping("info")
    @ResponseBody
    @ParseToken
    public R fileInfo(String userId, String fileId) throws BBYException {
        if (ObjectUtil.isEmpty(fileId)) {
            fileId = userId;
        }
        BBYUtils.checkEmpty(fileId);
        return R.ok(fileService.getFileInfo(userId, fileId));
    }
    /**
     * 获取多个文件信息
     *
     * @param fileId 文件id
     */
    @GetMapping("infos")
    @ResponseBody
    @ParseToken
    public R fileInfos(String userId, @RequestParam("fileId") List<String> fileId) throws BBYException {
        if (ObjectUtil.isEmpty(fileId)) {
            return R.error(StatusCode.INPUT_ERROR,"参数为空");
        }
        BBYUtils.checkEmpty(fileId);
        return R.ok(fileService.getFileInfos(userId, fileId));
    }

    /**
     * 获取文件路径
     *
     * @param fileId 文件id
     */
    @GetMapping("path")
    @ResponseBody
    @ParseToken
    public R filePath(String userId, String fileId) throws BBYException {
        if (ObjectUtil.isEmpty(fileId)) {
            fileId = userId;
        }
        BBYUtils.checkEmpty(fileId);
        return R.ok().setData(fileService.getFilePath(userId, fileId));
    }

    /**
     * 获取文件列表
     *
     * @param action path:使用文件路径索引文件;id:使用文件id
     * @param target path/fileId值
     */
    @ParseToken
    @GetMapping("list/{action}")
    @ResponseBody
    public R fileList(String userId, @PathVariable String action, @RequestParam String target) throws BBYException {
        logger.debug("获取文件列表：userId={},action={},target={}", userId, action, target);
        if (ObjectUtil.isEmpty(action) || ObjectUtil.isEmpty(target)) {
            return R.error(StatusCode.INPUT_ERROR, "参数错误");
        }
        VirtualFileList fileList;
        if ("id".equalsIgnoreCase(action)) {
            fileList = fileService.getFileList(userId, target);
        } else if ("path".equalsIgnoreCase(action)) {
            if (target.startsWith("/")) {
                target = userId + target;
            }
            //先判断请求文件目录是否符合要求
            VirtualPath file = new VirtualPath(target);
            fileList = fileService.getFileList(userId, file);
        } else {
            return R.error(StatusCode.INPUT_ERROR, "参数错误");
        }
        return R.ok(fileList);
    }

    /**
     * 新建文件夹
     * @param parent 父目录
     * @param dirname
     */
    @ParseToken
    @RequestMapping("mkdir")
    public R mkdir(String userId, String parent, String dirname) throws BBYException {
        logger.debug("新建文件夹userId={},file={}", userId, dirname);
        return R.ok(fileService.mkdir(userId, parent,dirname));
    }


    /**
     * 修改文件权限, 必须登录
     *
     * @param req 请求参数
     */
    @ParseToken(require = true)
    @PostMapping("permission")
    public R permission(String userId, @RequestBody EditPermissionReq req) throws BBYException {
        logger.debug("修改文件权限 userId={}，req={}", userId, req);
        if (ObjectUtil.isEmpty(userId)) {
            return R.error(StatusCode.NON_AUTHORITY, "请登录！");
        }
        fileService.editPermission(userId, req);
        return R.ok(req);
    }

    /**
     * 文件操作,只能从文件id索引<br>
     * 复制/移动/删除文件夹时需要拥有文件夹下所有文件的权限
     * @param action 具体操作
     */
    @ParseToken
    @PostMapping("opera")
    @ResponseBody
    public R fileOp(String userId, @RequestBody FileActionReq action) throws BBYException {
        if (ObjectUtil.isEmpty(action.getOpera())) {
            return R.error("输入格式错误");
        }
        logger.debug("文件操作:userId={},action={}", userId, action);
        FileActionResult result;
        switch (action.getOpera()) {
            case "move":
            case "copy":
                result = fileService.copyAndMove(userId, action);
                break;
            case "rename":
                result = fileService.renameFile(userId, action);
                break;
            case "delete":
                result = fileService.deleteFile(userId, action);
                break;
            default:
                return R.error("参数错误" + action.getOpera());
        }
        if (result.isAllOk()) {
            return R.ok();
        } else if (result.isAllError()) {
            return R.error(StatusCode.UNKNOWN_ERROR).setData(result.getMap());
        }
        return R.error(StatusCode.PART_FINISHED).setData(result.getMap());

    }
    /**
     * 举报文件
     */
    @PostMapping("report")
    @ParseToken
    public R reportFile(String userId,@RequestBody FileReport report) throws BBYException {
        BBYUtils.checkEmpty(report.getFileId());
        if (ObjectUtil.isNotEmpty(userId)) {
            report.setUserId(userId);
        }
        fileService.reportFile(report);
        return R.ok(report);
    }
}
